package productions;

import exceptions.ParserException;
import lexico.ErrorTable;
import lexico.SymbolTable;
import lexico.TokenClass;

/**
 * @author heekinho
 */
public class InstrucaoProduction extends AbstractProductionRule {

    /* Muitos dos métodos irão precisar de algo assim: */
    private static InstrucaoProduction instance = new InstrucaoProduction();

    public static InstrucaoProduction getInstance() {
        return instance;
    }

    /**
     * Regra: instrucao : (variaveis ';' | comandos | sentenca ';') | bloco;
     * @return
     * @throws ParserException
     */
    @Override
    public boolean analyze(SymbolTable st, ErrorTable et) throws ParserException {
        if (VariaveisProduction.getInstance().analyze(st, et)) {
            if (basicParse(st, TokenClass.DELIMITER_SEMICOLON)) {
                return true;
            }
            return skipUntilSynchronize(st, et, "Era esperado um ';'");
        }

        if (ComandosProduction.getInstance().analyze(st, et)) {
            return true;
        }

        if (SentencaProduction.getInstance().analyze(st, et)) {
            if (basicParse(st, TokenClass.DELIMITER_SEMICOLON)) {
                return true;
            }
            return skipUntilSynchronize(st, et, "Era esperado um ';'");
        }

        if (BlocoProduction.getInstance().analyze(st, et)) {
            return true;
        }

        return false;
    }

    @Override
    protected void populateFirst() {
        //from variaveis first
        first.add(TokenClass.KEYWORD_VARIAVEIS);

        //from comandos first
        first.add(TokenClass.KEYWORD_SE);
        first.add(TokenClass.KEYWORD_PARA);
        first.add(TokenClass.KEYWORD_ENQUANTO);
        first.add(TokenClass.KEYWORD_LEIA);
        first.add(TokenClass.KEYWORD_ESCREVA);

        //from sentenca first
        first.add(TokenClass.IDENTIFIER);

        //from bloco first
        first.add(TokenClass.DELIMITER_OPENING_CURLY_BRACKET);
    }

    @Override
    protected void populateFollow() {
        follow.add(TokenClass.DELIMITER_CLOSING_CURLY_BRACKET);
    }

}
